﻿using System;
using System.Windows.Forms;
using System.Drawing;
using System.Reflection;
using System.Windows;
using System.ComponentModel;


namespace SqlAServer
{

    public static class MinimizeToTray
    {
        /// <summary>
        /// Enables "minimize to tray" behavior for the specified Window.
        /// </summary>
        /// <param name="window">Window to enable the behavior for.</param>
        public static void Enable(Window window)
        {
            // No need to track this instance; its event handlers will keep it alive
            new MinimizeToTrayInstance(window);
        }

        /// <summary>
        /// Class implementing "minimize to tray" functionality for a Window instance.
        /// </summary>
        private class MinimizeToTrayInstance
        {
            private Window window;
            private NotifyIcon NotifyIcon;
            private bool IsIcon = false;

            /// <summary>
            /// Initializes a new instance of the MinimizeToTrayInstance class.
            /// </summary>
            /// <param name="window">Window instance to attach to.</param>
            public MinimizeToTrayInstance(Window win)
            {                
                window = win;
                window.StateChanged += new EventHandler(HandleStateChanged);
                window.Closing += new CancelEventHandler(Window_Closing);
            }

            private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
            {
                if (!IsIcon)
                {
                    e.Cancel = true;                    
                    window.WindowState = WindowState.Minimized;
                }
            }

            /// <summary>
            /// Handles the Window's StateChanged event.
            /// </summary>
            /// <param name="sender">Event source.</param>
            /// <param name="e">Event arguments.</param>
            private void HandleStateChanged(object sender, EventArgs e)
            {
                if (NotifyIcon == null)
                {
                    // Initialize NotifyIcon instance "on demand"
                    NotifyIcon = new NotifyIcon();
                    NotifyIcon.Icon =Icon.ExtractAssociatedIcon(Assembly.GetEntryAssembly().Location);
                    NotifyIcon.MouseClick += new MouseEventHandler(HandleNotifyIconOrBalloonClicked);
                    //NotifyIcon.BalloonTipClicked += new EventHandler(HandleNotifyIconOrBalloonClicked);
                }
                // Update copy of Window Title in case it has changed
                NotifyIcon.Text = window.Title;

                // Show/hide Window and NotifyIcon
                var minimized = (window.WindowState == WindowState.Minimized);
                window.ShowInTaskbar = !minimized;
                NotifyIcon.Visible = minimized;
                NotifyIcon.ShowBalloonTip(1000, null, window.Title, ToolTipIcon.None);
                if (window.WindowState == WindowState.Minimized) { IsIcon = true; }
            }

            /// <summary>
            /// Handles a click on the notify icon or its balloon.
            /// </summary>
            /// <param name="sender">Event source.</param>
            /// <param name="e">Event arguments.</param>
            private void HandleNotifyIconOrBalloonClicked(object sender, EventArgs e)
            {
                // Restore the Window
                if (((MouseEventArgs)e).Button == System.Windows.Forms.MouseButtons.Left)
                {
                    window.WindowState = WindowState.Normal;
                    IsIcon = false;
                }
                if (((MouseEventArgs)e).Button == System.Windows.Forms.MouseButtons.Right)
                    window.Close();
            }
        }
    }
}
